package cn.demoncat.util.ip;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

import cn.demoncat.util.exception.ParamRuntimeException;
import cn.demoncat.util.ip.TaobaoIpUtil.IpResult.ResultConstant;
import cn.demoncat.util.lang.JsonUtil;
import cn.demoncat.util.lang.constant.StringConstant;
import cn.demoncat.util.web.HttpUrlUtil;
import cn.demoncat.util.web.IpUtil;
import cn.demoncat.util.web.constant.IpConstant;

/**
 * IP查询 - 淘宝IP库
 * 
 * 网址：http://ip.taobao.com
 * 说明：IP库每周更新一次；未经书面同意，禁止私自对接，禁止商用；每个用户的访问频率需小于1qps
 * 注意：该接口有时会无法访问
 * 
 * @author 延晓磊
 *
 * @since 2018年11月14日
 */
public final class TaobaoIpUtil {

	/**
	 * REST-API
	 */
	private static final String REST_API = "http://ip.taobao.com/service/getIpInfo.php?ip=";
	
	/**
	 * 未知 - id
	 */
	private static final String UNKNOWN_ID = "";
	
	/**
	 * 内网IP - id
	 */
	private static final String INTRANET_ID = "local";
	
	private static final Logger LOG = LoggerFactory.getLogger(TaobaoIpUtil.class);
	
	/**
	 * 查询IP信息
	 * 
	 * @param ip
	 * @return 成功返回IpResult，失败返回null
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年11月14日
	 */
	public static IpResult get(String ip) {
		//IP校验
		if (!IpUtil.isIpAddr(ip)) {
			throw ParamRuntimeException.ILLEGAL;
		}
		//请求API
		String result;
		try {
			result = HttpUrlUtil.doGet(REST_API + ip);
		} catch (Exception e) {
			LOG.error("通过淘宝IP库查询IP失败：ip = " + ip, e);
			return null;
		}
		//请求结果
		JSONObject parse = JsonUtil.parseObject(result);
		if (parse.getInteger("code") == 0) {
			//解析
			IpResult res = JsonUtil.parse(parse.getString("data"), IpResult.class);
			//内网IP
			if (res.getIsp_id().equals(INTRANET_ID)) {
				return ResultConstant.INTRANET_RESULT;
			}else {
				//未知信息
				res.setCountry(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getCountry()) ? IpConstant.COUNTRY_TEXT_UNKNOWN : res.getCountry());
				res.setRegion(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getRegion()) ? StringConstant.EMPTY : res.getRegion());
				res.setCity(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getCity()) ? StringConstant.EMPTY : res.getCity());
				res.setIsp(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getIsp()) ? StringConstant.EMPTY : res.getIsp());
				res.setCountry_id(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getCountry_id()) ? UNKNOWN_ID : res.getCountry_id());
				res.setRegion_id(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getRegion_id()) ? StringConstant.EMPTY : res.getRegion_id());
				res.setCity_id(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getCity_id()) ? StringConstant.EMPTY : res.getCity_id());
				res.setIsp_id(ResultConstant.UNKNOWN.equalsIgnoreCase(res.getIsp_id()) ? StringConstant.EMPTY : res.getIsp_id());
			}
			return res;
		}else {
			LOG.error("通过淘宝IP库查询IP失败：ip = {}", ip);
			return null;
		}
	}
 
	/**
	 * IP查询结果
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年11月14日
	 */
	public static final class IpResult{
		
		/**
		 * 结果常量
		 * 
		 * @author 延晓磊
		 *
		 * @since 2018年11月14日
		 */
		public static final class ResultConstant{
			//未知
			public static final String UNKNOWN = "XX";
			//内网IP信息
			public static final IpResult INTRANET_RESULT = IpResult.getIntranet();
		}
		
		//国家
		private String country;
		//国家ID
		private String country_id;
		//省
		private String region;
		//省ID
		private String region_id;
		//市
		private String city;
		//市ID
		private String city_id;
		//运营商 
		private String isp;
		//运营商ID
		private String isp_id;
		
		/**
		 * 创建内网Result
		 * 
		 * @return
		 * 
		 * @author 延晓磊
		 *
		 * @since 2018年11月14日
		 */
		public static IpResult getIntranet() {
			IpResult res = new IpResult();
			res.setCountry(IpConstant.COUNTRY_TEXT_INTRANET);
			res.setRegion(StringConstant.EMPTY);
			res.setCity(StringConstant.EMPTY);
			res.setIsp(StringConstant.EMPTY);
			res.setCountry_id(INTRANET_ID);
			res.setRegion_id(StringConstant.EMPTY);
			res.setCity_id(StringConstant.EMPTY);
			res.setIsp_id(StringConstant.EMPTY);
			return res;
		}
		
		public String getCountry() {
			return country;
		}
		public void setCountry(String country) {
			this.country = country;
		}
		public String getCountry_id() {
			return country_id;
		}
		public void setCountry_id(String country_id) {
			this.country_id = country_id;
		}
		public String getRegion() {
			return region;
		}
		public void setRegion(String region) {
			this.region = region;
		}
		public String getRegion_id() {
			return region_id;
		}
		public void setRegion_id(String region_id) {
			this.region_id = region_id;
		}
		public String getCity() {
			return city;
		}
		public void setCity(String city) {
			this.city = city;
		}
		public String getCity_id() {
			return city_id;
		}
		public void setCity_id(String city_id) {
			this.city_id = city_id;
		}
		public String getIsp() {
			return isp;
		}
		public void setIsp(String isp) {
			this.isp = isp;
		}
		public String getIsp_id() {
			return isp_id;
		}
		public void setIsp_id(String isp_id) {
			this.isp_id = isp_id;
		}
		@Override
		public String toString() {
			return "IpResult [country=" + country + ", country_id=" + country_id + ", region=" + region + ", region_id="
					+ region_id + ", city=" + city + ", city_id=" + city_id + ", isp=" + isp + ", isp_id=" + isp_id
					+ "]";
		}
	}
}
